package webClient.UserInterfaceApplet;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;

import server.BuddyList;
import server.Group;
import server.Person;
import server.Status;
import webClient.ChatEngine.RequestHandler;
import webClient.ChatEngine.RequestSender;
import webClient.UserInterfaceClasses.WebChat;
import UserInterfaceClasses.BuddyList1;

import communication.AcceptNewBuddyRequest;
import communication.AddNewBuddyRequest;
import communication.AddNewGroupRequest;
import communication.ConfirmNewBuddyRequest;
import communication.InviteBuddyChatRoomRequest;
import communication.OpenConversationRequest;
import communication.RejectNewBuddyRequest;
import communication.RemoveBuddyFromGroupRequest;
import communication.RemoveGroupRequest;
import communication.SendMessageRequest;
public class buddyList extends JApplet implements ActionListener {
 
	public static InetAddress serverIP;
	public static InetAddress clientIP;
	public static int serverPort= 44444;
	public static int clientPort = 54321;
	
	/*static{
		try{
			serverIP = InetAddress.getByAddress(ser);
			clientIP = InetAddress.getLocalHost();
			
			System.out.println(clientIP);
		}catch(Exception e){
			
		}
	}*/
	
	// This initializes the sizing of the window and messenger name
	protected static final String APP_NAME = "Parlanchin Messenger";
	protected static final int X_SIZE = 200;
	protected static final int Y_SIZE = 600;
	BuddyList1 cBuddyList = new BuddyList1();
	String[] name = {"one","two", "three"};
	String[] group= {"1","2", "3"};
	private String username;
	
	public static Thread handler;
	
	JButton addBuddyButton = new JButton("Add Buddy");
	JButton deleteBuddyButton = new JButton("Del. Buddy");
	JButton addGroupButton = new JButton("Add Group");
	JButton deleteGroupButton = new JButton("Del. Group");
	
	//Thread t1 = new Thread(myApplet);
	// This creates the JTree to potentially create groups from 
	
	private JList onlineList;
	private JList offlineList;
	private BuddyList myBuddies = null;
	private HashMap<String, WebChat> chats = null;

	private static buddyList instance = null; 
	
	// This lays out the inner functionalities of the GUI
	public buddyList() {
		
	//	super(APP_NAME);
		setSize(X_SIZE, Y_SIZE);
		getContentPane().setLayout(new BorderLayout());
		
		// This is the layout for the buttons 
		JPanel cp = new JPanel();
		cp.setBackground(Color.white);
		cp.setLayout(new BorderLayout());
	
		cp.add(addBuddyButton,BorderLayout.EAST);
	    cp.add(deleteBuddyButton,BorderLayout.WEST);
	    
	    cp.add(addGroupButton, BorderLayout.NORTH);
	    cp.add(deleteGroupButton,BorderLayout.SOUTH);
	    
		getContentPane().add(cp, BorderLayout.SOUTH);
        
		chats = new HashMap<String, WebChat>();
		
        addBuddyButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				String name = JOptionPane.showInputDialog("Insert buddy name:");
				
				if(name != null){
					String group = JOptionPane.showInputDialog("Insert group name:");
					
					addBuddyToGroup(name, group);
				}
			}
		});
        
        deleteBuddyButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				String name = JOptionPane.showInputDialog("Insert buddy name to be deleted:");
				
				if(name != null){
					deleteBuddy(name);
				}
			}
		});
        
        addGroupButton.addActionListener(new ActionListener(){
        	
        	public void actionPerformed(ActionEvent e)
			{
				String name = JOptionPane.showInputDialog("Insert group name:");
				
				if(name != null){
					addGroup(name);
				}
			}
        	
        });
        
        deleteGroupButton.addActionListener(new ActionListener(){
        	
        	public void actionPerformed(ActionEvent e)
			{
				String name = JOptionPane.showInputDialog("Insert group name:");
				
				if(name != null){
					removeGroup(name);
				}
			}
        	
        });
        
        onlineList = new JList();
        
        onlineList.addMouseListener(new MouseListener(){

			@Override
			public void mouseClicked(MouseEvent arg0) {
				onlineListClick(arg0);
			}

			@Override
			public void mouseEntered(MouseEvent arg0) {
				
			}

			@Override
			public void mouseExited(MouseEvent arg0) {
				
			}

			@Override
			public void mousePressed(MouseEvent arg0) {
				
			}

			@Override
			public void mouseReleased(MouseEvent arg0) {
				
			}
        	
        });
        
        
        JScrollPane s = new JScrollPane(onlineList);
		getContentPane().add(s, BorderLayout.CENTER);
		s.setBackground(Color.white);
		
		/*offlineList = new JList();
        JScrollPane s2 = new JScrollPane(offlineList);
		getContentPane().add(s2, BorderLayout.CENTER);
		s.setBackground(Color.white);*/
		
		// Here JScrollBar creates a scrollbar in the instant messenger GUI for
		// easy viewing of buddies when many are on. 
		JScrollBar vbar = new JScrollBar(JScrollBar.VERTICAL, 0, 40, 0, 100);
		add(vbar, BorderLayout.EAST);
		
	}

	public void login() {
		  boolean userValid = false;
		  LoginApplet login = new LoginApplet (new Frame(""));
		  //requestFocus();
/*		  if (login.id) {
			  setUser(login.username.getText());
			  String password = login.password.getText();
		  }
		  else{
			  System.out.println("Cancel was pressed.");
		  }*/
			
		  //login.dispose();

	}	
	
	
	// Main method to begin the buddy list. 
	@SuppressWarnings("unchecked")
	public void init() {

		try {
			byte s1 = (byte) Integer.parseInt(buddyList.this.getParameter("s1"));
			byte s2 = (byte) Integer.parseInt(buddyList.this.getParameter("s2"));
			byte s3 = (byte) Integer.parseInt(buddyList.this.getParameter("s3"));
			byte s4 = (byte) Integer.parseInt(buddyList.this.getParameter("s4"));
			byte[] ser = new byte[]{(byte) s1, (byte) s2, s3, s4};
			
			byte c1 = (byte) Integer.parseInt(buddyList.this.getParameter("c1"));
			byte c2 = (byte) Integer.parseInt(buddyList.this.getParameter("c2"));
			byte c3 = (byte) Integer.parseInt(buddyList.this.getParameter("c3"));
			byte c4 = (byte) Integer.parseInt(buddyList.this.getParameter("c4"));
			byte[] cli = new byte[]{(byte)c1, (byte)c2, c3, c4};
			
			serverIP = InetAddress.getByAddress(ser);
			clientIP = InetAddress.getByAddress(cli);
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		RequestHandler request = new RequestHandler(clientPort);
		RequestSender.setUpServer(serverIP, serverPort, clientIP, clientPort);
		handler = new Thread(request);
		handler.start();
		
		instance = this;
		
		login();
	}

	public void setUser(String username)
	{
		this.username = username;
	}

	public String getUsername()
	{
		return username;
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	public static void launchBuddyList(){
		
		//instance = new buddyList();
		//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//	instance.setVisible(true);
	}
	
	public void displayBuddyList(BuddyList bl){
		
		myBuddies = bl;
		
		Iterator<Group> itgroup = bl.getGroups();
        ArrayList<String> online = new ArrayList<String>();
        ArrayList<String> offline = new ArrayList<String>();
        
		while(itgroup.hasNext())
		{
			Group g = itgroup.next();
			
			online.add(g.getName());
			offline.add(g.getName());
			
			Iterator<Person> buddyIterator = g.getMembers();
			
			while(buddyIterator.hasNext())
			{
				Person p = buddyIterator.next();
				if(p.getStatus() == Status.ONLINE){
					online.add("  " + p.getUsername());
				}
			}
		}
		
		String[] names = new String[online.size()];
		online.toArray(names);
		final String[] content = names;
		
		onlineList.setModel(new javax.swing.AbstractListModel() {
			private static final long serialVersionUID = 1L;
			
			String[] strings = content;
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
		
	}
	
	public static buddyList getInstance(){
		
		return instance;
		
	}
	
	private void onlineListClick(MouseEvent evt) {
		
		if(evt.getClickCount() >= 2){
			String selected = (String) onlineList.getSelectedValue();
			
			if(selected != null){
				if(selected.startsWith("  ")){
					OpenConversationRequest r = new OpenConversationRequest(username, selected.substring(2));
					RequestSender.serverSender.sendRequest(r);
				}
			}
		}
		
	}
	
	public void createChat(String id){
		
		WebChat c = new WebChat(id);
		c.setEngine(this);
		
		chats.put(id, c);
		
	}
	
	public void removeChat(String id){
		
		chats.remove(id);
		
	}
	
	public void deliverMessage(String id, String sender, String message){
		
		WebChat c = chats.get(id);
		
		if(c != null){
			c.deliverMessage(sender, message);
		}
		
	}
	
	public void sendMessage(String message, String convID){
		
		SendMessageRequest r = new SendMessageRequest(this.username, convID, message);
		RequestSender.serverSender.sendRequest(r);
		
	}
	
	public void updateStatus(Person changed){
		
		Iterator<Group> itgroup = myBuddies.getGroups();
		
		while(itgroup.hasNext()){
			Group g = itgroup.next();
			
			Person p = g.findPerson(changed.getUsername());
			
			if(p != null){
				p.setStatus(changed.getStatus());
			}
		}
		
		this.displayBuddyList(myBuddies);
	}
	
	public void inviteBuddy(String buddyName, String convid){
		
		Iterator<Group> itgroup = myBuddies.getGroups();
		
		while(itgroup.hasNext()){
			Group g = itgroup.next();
			
			Person p = g.findPerson(buddyName);
			if(p != null){
				if(p.getStatus() != Status.OFFLINE){
					InviteBuddyChatRoomRequest req = new InviteBuddyChatRoomRequest(this.username, buddyName, convid);
					RequestSender.serverSender.sendRequest(req);
					break;
				}
			}
		}
		
	}
	
	public void addBuddyToGroup(String name, String group){
		
		Group g = myBuddies.findGroup(group);
		
		if(g != null){
			Person p = new Person(name);
			g.addMember(p);
			
			AddNewBuddyRequest req = new AddNewBuddyRequest(this.username, group, name);
			RequestSender.serverSender.sendRequest(req);
			
		}else{
			JOptionPane.showMessageDialog(this, "Group doesn't exist");
		}
		
		this.displayBuddyList(myBuddies);
	}
	
	public void deleteBuddy(String name){
		
		Iterator<Group> it = myBuddies.getGroups();
		
		while(it.hasNext()){
			Group g = it.next();
			
			Person p = g.findPerson(name);
			
			if(p != null){
				g.removeMember(p);
				
				RemoveBuddyFromGroupRequest req = new RemoveBuddyFromGroupRequest(this.username, name, g.getName());
				RequestSender.serverSender.sendRequest(req);
			}
		}
		
		this.displayBuddyList(myBuddies);
	}
	
	public void addGroup(String name){
		
		Group g = new Group(name);
		
		myBuddies.addGroup(g);
		
		AddNewGroupRequest req = new AddNewGroupRequest(username, name);
		RequestSender.serverSender.sendRequest(req);
		
		this.displayBuddyList(myBuddies);
	}
	
	public void removeGroup(String name){
		
		Group g = myBuddies.findGroup(name);
		
		if(g != null){
			Iterator<Person> it = g.getMembers();
			
			if(it.hasNext()){
				JOptionPane.showMessageDialog(this, "Group cannot be deleted.");
			}else{
				myBuddies.removeGroup(g);
				
				RemoveGroupRequest req = new RemoveGroupRequest(username, name);
				RequestSender.serverSender.sendRequest(req);
			}
		}else{
			JOptionPane.showMessageDialog(this, "Group doesn't exist");
		}
		
		this.displayBuddyList(myBuddies);
	}
	
	public void confirmNewBuddy(ConfirmNewBuddyRequest req){
		
		int response = JOptionPane.showConfirmDialog(this, "Do you want to add " + req.getSender() + " as your friend?", "Confirm Buddy", JOptionPane.YES_NO_OPTION);
		
		if(response == JOptionPane.YES_OPTION){
			String group = JOptionPane.showInputDialog("Enter group name:");
			
			if(group != null){
				Group g = myBuddies.findGroup(group);
				
				if(g == null){
					this.addGroup(group);
					g = myBuddies.findGroup(group);
				}
				
				Person p = new Person(req.getSender());
				
				AcceptNewBuddyRequest accept = new AcceptNewBuddyRequest(username, group, req.getSender());
				RequestSender.serverSender.sendRequest(accept);
			}
		}else{
			RejectNewBuddyRequest reject = new RejectNewBuddyRequest(username, req.getSender());
			RequestSender.serverSender.sendRequest(reject);
		}
		
	}
}

